package com.cloudOffice.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudOffice.constant.GlobalConstant;
import com.cloudOffice.constant.HttpConstant;
import com.cloudOffice.execption.SystemException;
import com.cloudOffice.mapper.SysRoleMapper;
import com.cloudOffice.mapper.SysUserRoleMapper;
import com.cloudOffice.model.system.SysRole;
import com.cloudOffice.model.system.SysUserRole;
import com.cloudOffice.result.Result;
import com.cloudOffice.service.SysRoleService;
import com.cloudOffice.vo.system.AssignRoleVo;
import com.cloudOffice.vo.system.SysRoleQueryVo;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: cloud-office
 * @className: SysRoleServiceImpl
 * @description: SysRoleService
 * @data: 2024/2/4 15:51
 * @author: ihu
 * @version: 1.0
 **/

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
	
	@Resource
	private SysUserRoleMapper sysUserRoleMapper;
	
	
	@Override
	public Result<IPage<SysRole>> pageQueryRole(Long page, Long limit, SysRoleQueryVo sysRoleQueryVo) {
		Page<SysRole> pageParam = new Page<>(page, limit);
		LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
		wrapper.like(!StringUtils.isEmpty(sysRoleQueryVo.getRoleName()), SysRole::getRoleName,
				sysRoleQueryVo.getRoleName());
		return Result.success(page(pageParam, wrapper));
//		HashMap<String, Object> map = new HashMap<>();
//		map.put("page", pageModel.getCurrent());
//		map.put("pageSize", pageModel.getSize());
//		map.put("total", pageModel.getTotal());
//		map.put("rows", pageModel.getRecords());
//		return Result.success(map);
	}
	
	/**
	 * 根据用户id查询角色
	 */
	@Override
	public Map<String, Object> findRoleByAdminId(Long userId) {
		//查询所有的角色
		List<SysRole> allRolesList = list();
		//拥有的角色id
		List<Long> existRoleIdList =
				sysUserRoleMapper.selectList(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userId).select(SysUserRole::getRoleId)).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
		//对角色进行分类
		List<SysRole> assignedRoleList = allRolesList.stream()
				.filter(e -> existRoleIdList.contains(e.getId()))
				.collect(Collectors.toList());
		Map<String, Object> roleMap = new HashMap<>();
		roleMap.put("assignRoleList", assignedRoleList);
		roleMap.put("allRolesList", allRolesList);
		return roleMap;
		
		// existRoleIdList的大小和结构来决定是否使用并行流，若很小或没有足够的内存来处理并行流，那么顺序流可能更适合。
//		List<SysRole> assignedRoleList = allRolesList.stream()
//				.filter(role -> existRoleIdList.contains(role.getId()))
//				// 使用collectingAndThen收集列表，检查existRoleIdList是否是Set。
//				// 是，使用并行流来过滤列表。不是，保持顺序流
//				.collect(Collectors.collectingAndThen(Collectors.toList(), list -> {
//					if (existRoleIdList instanceof Set) {
//						return list.parallelStream().filter(role -> existRoleIdList.contains(role.getId())).collect
//						(Collectors
//						.toList());
//					} else {
//						return list;
//					}
//				}));
	}
	
	/**
	 * 执行分配角色
	 */
	@Transactional
	@Override
	public void doAssign(AssignRoleVo assignRoleVo) {
		List<Long> roleIdList = assignRoleVo.getRoleIdList();
		if (assignRoleVo.getUserId() == null || roleIdList == null || roleIdList.isEmpty()) {
			throw new SystemException(HttpConstant.CODE_400, GlobalConstant.PARAMETER_ERROR);
		}
		sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId,
				assignRoleVo.getUserId()));
		// 批量插入
		roleIdList.forEach(e -> {
			if (e != null) {
				sysUserRoleMapper.insert(SysUserRole.builder().userId(assignRoleVo.getUserId()).roleId(e).build());
			}
		});
		
	}
}
